package com.cctc.rds.raft.core;

import com.cctc.rds.raft.core.node.Node;
import com.cctc.rds.raft.core.node.NodeIpPort;
import com.cctc.rds.raft.core.rpc.heartbeat.HeartBeatListener;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Raft 集群 [共享] 信息
 */
public class RaftCluster {
    private static final Map<Integer, Node> NODE_MAP = new HashMap<>();
    private static final RaftClusterConfig CONFIG = RaftClusterConfig.builder().build();
    private static final AtomicReference<HeartBeatListener> HEART_BEAT_LISTENER_HOLDER = new AtomicReference<>(null);

    private RaftCluster() {
    }

    public static void init(Set<NodeIpPort> nodes) {
        setAllNodes(nodes);
    }

    private static void setAllNodes(Set<NodeIpPort> nodes) {
        for (NodeIpPort ipPort : nodes) {
            Node node = new Node(ipPort.getNodeId());
            node.setIpPort(ipPort);
            NODE_MAP.put(node.getId(), node);
        }
    }

    public static Set<Node> getAllNodes() {
        return new HashSet<>(NODE_MAP.values());
    }

    public static Node getNode(int nodeId) {
        return NODE_MAP.get(nodeId);
    }

    public static int nodeCount() {
        return NODE_MAP.size();
    }

    public static RaftClusterConfig getConfig() {
        return CONFIG;
    }

    public static void holdHeartBeatListener(HeartBeatListener listener) {
        HEART_BEAT_LISTENER_HOLDER.set(listener);
    }

    public static HeartBeatListener getHeartBeatListener() {
        return HEART_BEAT_LISTENER_HOLDER.get();
    }
}
